using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using launch.cframework;
using System;

public class BaseLaunchHotUpdate : MonoBehaviour
{
    public TextAsset startGameConfig;

    public enum State
    {
        None,
        HotUpdateDllMgrInitFailed,
        LoadDllCofnigNotFound,
        DeserializeLoadDllConfigFailed,
        LoadCodeFailed,
        LoadCodeBundleFailed,
        LoadHotUpdateSuccess,
        StartHotUpdateFailed,
        StartHotUpdateSuccess,
        StartGameFailed,
        StartGameSuccess,
    }

    protected IEnumerator Start()
    {
        var e = LoadHotUpdate().WithResult();
        yield return e;
        var a = (object[])e.Current;

        var loadHotUpdateState = (State)a[0];
        var flc = (LoadDllConfig)a[1];

        if (AppManager.GetAppInfo().enable_hotupdate)
        {
            if (flc == null && Application.isEditor)
            {
                flc = Newtonsoft.Json.JsonConvert.DeserializeObject<LoadDllConfig>(startGameConfig.text);
            }
        }

        if(flc != null)
        {
            var s = StartHotUpdate(flc).WithResult();
            yield return s;
            yield return s.Current;
        }
        
        if (AppManager.GetAppInfo().enable_hotupdate)
        {
            yield return loadHotUpdateState;
        }
        
        var e2 = StartGame().WithResult();
        yield return e2;
        yield return e2.Current;
    }

    protected IEnumerator StartHotUpdate(LoadDllConfig flc)
    {
        var ret = CommonUtil.CallMethodWithResult(flc.startHotUpdateDllNames[flc.startHotUpdateDllNames.Length - 1].Replace(".dll", ""), flc.startHotUpdateClassName, flc.startHotUpdateMethodName, new object[] { HotUpdateDllMgr.GetBundle(), null });
        var task = ((IEnumerator)ret.Item2).WithResult();
        yield return task;
        var result = (bool)task.Current;

        HotUpdateDllMgr.UnloadBundle();

        yield return result ? State.StartHotUpdateSuccess : State.StartHotUpdateFailed;
    }

    protected IEnumerator StartGame()
    {
        var flc = Newtonsoft.Json.JsonConvert.DeserializeObject<LoadDllConfig>(startGameConfig.text);

        var tempResult = CommonUtil.CallMethodWithResult(flc.startGameDllNames[flc.startGameDllNames.Length - 1].Replace(".dll", ""), flc.startGameClassName, flc.startGameMethodName, new object[] { flc.gameScene });
        var task = ((IEnumerator)tempResult.Item2).WithResult();
        yield return task;
        var taskResult = (bool)task.Current;

        yield return taskResult ? State.StartGameSuccess : State.StartGameFailed;
    }


    protected IEnumerator LoadHotUpdate()
    {
        if (!AppManager.GetAppInfo().enable_hotupdate)
        {
            yield return new object[] { State.None, null };
        }

        var e = HotUpdateDllMgr.init(null).WithResult();
        yield return e;
        var result = (bool)e.Current;

        if (HotUpdateDllMgr.latestVersionInfo == null)
        {
            yield return new object[] { State.HotUpdateDllMgrInitFailed, null };
        }

        var e2 = HotUpdateDllMgr.LoadBundle().WithResult();
        yield return e2;
        result = (bool)e2.Current;

        if (!result)
        {
            yield return new object[] { State.LoadCodeBundleFailed, null };
        }
        
        var configAsset = HotUpdateDllMgr.GetBundle().LoadAsset<TextAsset>(LoadDllConfig.fileName);
        if (configAsset == null)
        {
            yield return new object[] { State.LoadDllCofnigNotFound, null };
        }

        LoadDllConfig flc = null;
        try
        {
            flc = Newtonsoft.Json.JsonConvert.DeserializeObject<LoadDllConfig>(configAsset.text);
        }
        catch (System.Exception exception)
        {
            UnityEngine.Debug.LogException(exception);
        }

        if (flc == null)
        {
            yield return new object[] { State.DeserializeLoadDllConfigFailed, null };
        }

        var e3 = HotUpdateDllMgr.LoadCode(flc.startHotUpdateDllNames, false).WithResult();
        yield return e3;
        var a = (bool)e3.Current;

        var ab = HotUpdateDllMgr.GetBundle();
        if (ab != null)
        {
            yield return new object[] { State.LoadHotUpdateSuccess, flc };
        }
        else
        {
            yield return new object[] { State.LoadCodeFailed, null };
        }
    }
}